/*
 * OREKIT-X
 * Copyright 2002-2008 CS Communication & Systemes
 * 
 * Parts of this software package have been licensed to CS
 * Communication & Systemes (CS) under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work for
 * additional information.
 *  
 * This is an experimental copy of OREKIT from www.orekit.org.
 * Please use the original OREKIT from orekit.org for normal work
 * unrelated to this research project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You
 * may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package ore.bodies;

import ore.Frame;
import ore.Line;
import ore.errors.OrekitException;
import ore.time.AbsoluteDate;

import org.apache.commons.math.geometry.Vector3D;

/** 
 * Interface representing the rigid surface shape of a natural body.
 * 
 * The shape is not provided as a single complete geometric model, but
 * single points can be queried ({@link #getIntersectionPoint}).
 * 
 * @author Luc Maisonobe
 */
public interface BodyShape
    extends java.io.Serializable
{

    /**
     * @return Body frame related to body shape
     */
    public Frame getBodyFrame();

    /**
     * Get the intersection point of a line with the surface of the
     * body.
     * 
     * A line may have several intersection points with a closed
     * surface (we consider the one point case as a degenerated two
     * points case). The close parameter is used to select which of
     * these points should be returned. The selected point is the one
     * that is closest to the close point.
     * 
     * @param line Test line (may intersect the body or not)
     * @param close Point used for intersections selection
     * @param frame Frame in which line is expressed
     * @param date Date of the line in given frame
     * 
     * @return Intersection point at altitude zero or null if the line
     * does not intersect the surface
     * 
     * @exception OrekitException if line cannot be converted to body frame
     * 
     * @see ore.Line#getAbscissa(Vector3D)
     * @see ore.Line#pointAt(double)
     */
    public GeodeticPoint getIntersectionPoint(Line line, Vector3D close,
                                              Frame frame, AbsoluteDate date)
        throws OrekitException;

    /**
     * Transform a cartesian point to a surface-relative point.
     * 
     * @param point cartesian point
     * @param frame frame in which cartesian point is expressed
     * @param date date of the computation (used for frames conversions)
     * 
     * @return point at the same location but as a surface-relative point
     * 
     * @exception OrekitException if point cannot be converted to body frame
     */
    public GeodeticPoint transform(Vector3D point, Frame frame, AbsoluteDate date)
        throws OrekitException;

    /** 
     * Transform a surface-relative point to a cartesian point.
     * 
     * @param point surface-relative point
     * 
     * @return point at the same location but as a cartesian point
     */
    public Vector3D transform(GeodeticPoint point);

}
